home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 22 / CU Amiga Magazine's Super CD-ROM 22 (1998)(EMAP Images)(GB)[!][issue 1998-05].iso / PowerPC / System / PPCReleaseDEV / Tools / PPCDebug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-21  |  48.2 KB  |  1,566 lines

  1. /***************************************************************************
  2.  *
  3.  *                       PPCDebug
  4.  *
  5.  *  PPCDebug is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *
  10.  *
  11.  *  This started as a small example to show how to
  12.  *  use the ppc.library`s trap function and grew into
  13.  *  a small, not very polished but useful, PPC debugger.
  14.  *
  15.  *  I`m sure you would like to see more features and because
  16.  *  the source is public it should be easy to add the needed
  17.  *  functions personally.
  18.  *  But to coordinate this I suggest to contact me if these
  19.  *  features should be available to everybody.
  20.  *
  21.  *  Ralph Schmidt
  22.  *
  23.  *
  24.  *
  25.  ***************************************************************************/
  26.  
  27. #include <exec/types.h>
  28. #include <exec/nodes.h>
  29. #include <exec/lists.h>
  30. #include <exec/libraries.h>
  31. #include <exec/memory.h>
  32. #include <exec/alerts.h>
  33. #include <exec/interrupts.h>
  34. #include <clib/alib_stdio_protos.h>
  35. #include <dos/dos.h>
  36. #include <dos/dosextens.h>
  37. #include <dos/dostags.h>
  38. #include <proto/exec.h>
  39. #include <proto/dos.h>
  40. #include <PowerUP/PPCLib/Interface.h>
  41. #include <PowerUP/PPCLib/tasks.h>
  42. #include <PowerUP/PPCLib/ppc.h>
  43. #include <PowerUP/PPCLib/object.h>
  44. #include <PowerUP/PPCDisslib/PPCDiss.h>
  45. #include <PowerUP/pragmas/ppc_pragmas.h>
  46. #include <PowerUP/clib/ppc_protos.h>
  47. #include <PowerUP/pragmas/ppcdiss_pragmas.h>
  48. #include <PowerUP/clib/ppcdiss_protos.h>
  49. #include <ctype.h>
  50. #include <string.h>
  51. #include <stdlib.h>
  52. #include "PPCDebug_VERSION.h"
  53. #include "/ArgParser/ArgParser.h"
  54. #include "/ArgParser/ArgParser_protos.h"
  55.  
  56. void __builtin_emit(int);
  57.  
  58. struct    BreakPoint
  59. {
  60.     struct Node    Node;
  61.     ULONG        *Address;
  62.     ULONG        Opcode;
  63. };
  64.  
  65. #define    EMPTYTRACEPOINT    ((ULONG*)0xffffffff)
  66.  
  67. #define    LINEMAX        256
  68.  
  69.  
  70. /* Quick Signal hack because i'm too lazy
  71.  * to use AllocSignal()
  72.  */
  73.  
  74. #define    SIGNAL_EXCEPTION    31
  75.  
  76.  
  77. #define    MSRF_FP        0x2000
  78.  
  79.  
  80. #define    OPCODE_LR    0x1
  81. #define    OPCODE_TD31_0_0    0x7fe00008
  82.  
  83. #define    MASK_21_30(x)    (x &((1<<(31-21))|(1<<(31-22))|(1<<(31-23))|(1<<(31-24))|(1<<(31-25))|(1<<(31-26))|(1<<(31-27))|(1<<(31-28))|(1<<(31-29))|(1<<(31-30))))
  84. #define    OP_ID(a,b,c,d,e,f,g,h,i,j)  ((1<<10)*a | \
  85.                                       (1<<9)*b | \
  86.                                       (1<<8)*c | \
  87.                                       (1<<7)*d | \
  88.                                       (1<<6)*e | \
  89.                                       (1<<5)*f | \
  90.                                       (1<<4)*g | \
  91.                                       (1<<3)*h | \
  92.                                       (1<<2)*i | \
  93.                                       (1<<1)*j)
  94.  
  95.  
  96. extern struct ExecBase    *SysBase;
  97. extern struct Library    *DosBase;
  98. struct Library        *PPCLibBase;
  99. struct Library        *PPCDissBase;
  100. BPTR            stdout;
  101. struct Hook        MyHook;
  102. struct Hook        MyAddressHook;
  103. struct Hook        MySymbolHook;
  104. struct Hook        MyRelocHook;
  105. struct Hook        MyScanSymbolHook;
  106. struct Hook        MyArgParserSymbolHook;
  107. struct Hook        MyGetDataHook;
  108. struct Process        *MsgProcess;
  109. struct ExceptionMsg    ExceptionMsg;
  110. void            *ExceptionTask;
  111. BPTR            InputFile;
  112. BPTR            OutputFile;
  113. ULONG            CPU;
  114. ULONG            PC;
  115. ULONG            NewPC;
  116. ULONG            MEM;
  117. struct PPCObjectInfo    MyInfo;
  118. void            *MyObject;
  119. BOOL            MyInfoStatus;
  120. extern ULONG        __base;
  121. struct List        BreakPointList;
  122. struct BreakPoint    MyTracePoint;
  123. BOOL            GoSimulateFlag;
  124.  
  125.  
  126. UBYTE    vers[] = VERSTAG;
  127.  
  128. char    *ExceptionStringTable[]=
  129. {
  130.     "Unknown",
  131.     "Reset",
  132.     "Machine Check",
  133.     "Data Access",
  134.     "Instruction Access",
  135.     "External Interrupt",
  136.     "Alignment",
  137.     "Program",
  138.     "FPU Unavailable",
  139.     "Decrementer",
  140.     "Interface Error",
  141.     "Reserved B",
  142.     "System Call",
  143.     "Trace",
  144.     "FPU Assist",
  145.     "Reserved F",
  146.     "Instruction Translation Miss",
  147.     "Data Load Translation Miss",
  148.     "Data Store Translation Miss",
  149.     "Instruction Address Point",
  150.     "System Management Interrupt"
  151. };
  152.  
  153. /*------------------------------------------------------------------------*/
  154. /*------------------------------------------------------------------------*/
  155. /*------------------------------------------------------------------------*/
  156. /*------------------------------------------------------------------------*/
  157. /*------------------------------------------------------------------------*/
  158. /*------------------------------------------------------------------------*/
  159. /*------------------------------------------------------------------------*/
  160. /*------------------------------------------------------------------------*/
  161.  
  162. BOOL    GetValue(char    *Ptr,
  163.                  ULONG    *Result)
  164. {
  165. struct TagItem    MyTags[5];
  166. ULONG        Error;
  167. ULONG        Type;
  168. void        *MyParseHandle;
  169.  
  170.   Type            =    PARSETYPE_INTEGER;
  171.  
  172.   MyTags[0].ti_Tag    =    PARSETAG_ERROR;
  173.   MyTags[0].ti_Data    =    (ULONG) &Error;
  174.   MyTags[1].ti_Tag    =    PARSETAG_VALUE;
  175.   MyTags[1].ti_Data    =    (ULONG) Result;
  176.   MyTags[2].ti_Tag    =    PARSETAG_TYPE;
  177.   MyTags[2].ti_Data    =    (ULONG) &Type;
  178.   MyTags[3].ti_Tag    =    PARSETAG_SYMBOLHOOK;
  179.   MyTags[3].ti_Data    =    (ULONG) &MyArgParserSymbolHook;
  180.   MyTags[4].ti_Tag    =    TAG_END;
  181.  
  182.   if (MyParseHandle=CreateParseHandle(MyTags))
  183.   {
  184.     MyTags[0].ti_Tag    =    TAG_END;
  185.     if (ParseArgument(MyParseHandle,
  186.                       Ptr,
  187.                       MyTags))
  188.     {
  189.       return(TRUE);
  190.     }
  191.     else
  192.     {
  193.       printf("Error 0x%08lx\n",Error);
  194.     }
  195.   }
  196.   else
  197.   {
  198.     printf("Not enough memory\n");
  199.   }
  200.   return(FALSE);
  201. }
  202.  
  203.  
  204. /*------------------------------------------------------------------------*/
  205. /*------------------------------------------------------------------------*/
  206. /*------------------------------------------------------------------------*/
  207. /*------------------------------------------------------------------------*/
  208. /*------------------------------------------------------------------------*/
  209. /*------------------------------------------------------------------------*/
  210. /*------------------------------------------------------------------------*/
  211. /*------------------------------------------------------------------------*/
  212.  
  213. BOOL    ShowDiss(ULONG    Address,
  214.                  ULONG    Lines,
  215.                  BOOL    ShowData)
  216. {
  217. void        *PPCDissHandle;
  218. int        i;
  219. char        LineBuffer[128];
  220. struct TagItem    MyTags[1];
  221.  
  222. //  __builtin_emit(0x4afc);
  223.  
  224.   MyTags[0].ti_Tag    =    TAG_END;
  225.  
  226. //  Printf("PC: 0x%08lx::\n",Address);
  227.  
  228.   if (PPCDissHandle = CreateDisAssHandleTags(DISASS_DEFINEPC,Address,
  229.                                              DISASS_SHOWDATA,ShowData,
  230.                                              DISASS_USEDC68KDESC, TRUE,
  231.                                              DISASS_ADDRESSHOOK,&MyAddressHook,
  232.                                              DISASS_SYMBOLHOOK,&MySymbolHook,
  233.                                              DISASS_RELOCHOOK,&MyRelocHook,
  234.                                              DISASS_GETDATAHOOK,&MyGetDataHook,
  235.                                              TAG_DONE))
  236.   {
  237.     for(i=0;i<Lines;i++)
  238.     {
  239.       if (MyInfoStatus==FALSE ||
  240.           (MyInfo.Address==0 && MyInfo.Size==0) ||
  241.           (MyInfo.Type==PPCELFINFOTYPE_SECTION) ||
  242.           (Address < MyInfo.Address || Address >= (MyInfo.Address+MyInfo.Size)))
  243.       {
  244. //    __builtin_emit(0x4afc);
  245.         MyInfo.Name        =    NULL;
  246.         MyInfo.Address        =    Address;
  247.         MyInfo.Size        =    0;
  248.         MyInfoStatus=PPCGetObjectAttrs(MyObject,
  249.                                        &MyInfo,
  250.                                        MyTags);
  251.  
  252. //        Printf("Find New Symbol Status=%ld\n",MyInfoStatus);
  253.       }
  254.  
  255.  
  256.       DisAssTags(PPCDissHandle,
  257.                  DISASS_BUFFER,LineBuffer,
  258.                  TAG_DONE);
  259.       if (MyInfoStatus)
  260.       {
  261.         Printf("%s+0x%lx: %s\n",
  262.                MyInfo.Name,
  263.                Address - MyInfo.Address,
  264.                LineBuffer);
  265.       }
  266.       else
  267.       {
  268.         if (Address < 0xfff00000 || Address >= 0xfff10000)
  269.         {
  270.           Printf("0x%lx: %s\n",
  271.                  Address,
  272.                  LineBuffer);
  273.         }
  274.         else
  275.         { 
  276.           MyInfo.Name        =    "Kernel";
  277.           MyInfo.Address    =    0xfff00000;
  278.           MyInfo.Size        =    0x10000;
  279.           /* Setting MyInfoStatus to false
  280.            * has the effect that it searches again for symbols
  281.            * otherwise it would find dynamic link symbols after
  282.            * it showed a kernel symbol
  283.            */
  284.           MyInfoStatus        =    FALSE;
  285.           Printf("%s+0x%lx: %s\n",
  286.                  MyInfo.Name,
  287.                  Address - MyInfo.Address,
  288.                  LineBuffer);
  289.         }
  290.       }
  291.       Address    +=    4;
  292.     }
  293.     DeleteDisAssHandle(PPCDissHandle);
  294.     NewPC    =    Address;
  295.     return(TRUE);
  296.   }
  297.   else
  298.   {
  299.     return(FALSE);
  300.   }
  301. }
  302.  
  303. BOOL    ShowMem(ULONG    Address,
  304.                 ULONG    Lines)
  305. {
  306. int    i;
  307.   for (i=0;i<Lines;i++)
  308.   {
  309.     Printf("%08lx: %08lx %08lx %08lx %08lx\n",
  310.            Address,
  311.            PPCReadLong((ULONG*) (Address+0x00)),
  312.            PPCReadLong((ULONG*) (Address+0x04)),
  313.            PPCReadLong((ULONG*) (Address+0x08)),
  314.            PPCReadLong((ULONG*) (Address+0x0c)));
  315.     Address    +=    16;
  316.   }
  317.   return(TRUE);
  318. }
  319.  
  320.  
  321. /*------------------------------------------------------------------------*/
  322. /*------------------------------------------------------------------------*/
  323. /*------------------------------------------------------------------------*/
  324. /*------------------------------------------------------------------------*/
  325. /*------------------------------------------------------------------------*/
  326. /*------------------------------------------------------------------------*/
  327. /*------------------------------------------------------------------------*/
  328. /*------------------------------------------------------------------------*/
  329.  
  330. void    ShowRegsGPR(void)
  331. {
  332. int    i;
  333.   for (i=0;i<32;i+=8)
  334.   {
  335.     Printf("GPR %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
  336.            ExceptionMsg.GPR[i+0],
  337.            ExceptionMsg.GPR[i+1],
  338.            ExceptionMsg.GPR[i+2],
  339.            ExceptionMsg.GPR[i+3],
  340.            ExceptionMsg.GPR[i+4],
  341.            ExceptionMsg.GPR[i+5],
  342.            ExceptionMsg.GPR[i+6],
  343.            ExceptionMsg.GPR[i+7]);
  344.   }
  345. }
  346.  
  347. void    ShowRegsFPR(void)
  348. {
  349. int    i;
  350.   if (ExceptionMsg.SRR1 & MSRF_FP)
  351.   {
  352.     Printf("FPSCR %08lx\n",
  353.             ExceptionMsg.FPSCR);
  354.  
  355.     for (i=0;i<32;i+=8)
  356.     {
  357.       printf("FPR %g %g %g %g %g %g %g %g\n",
  358.              ExceptionMsg.FPR[i+0],
  359.              ExceptionMsg.FPR[i+1],
  360.              ExceptionMsg.FPR[i+2],
  361.              ExceptionMsg.FPR[i+3],
  362.              ExceptionMsg.FPR[i+4],
  363.              ExceptionMsg.FPR[i+5],
  364.              ExceptionMsg.FPR[i+6],
  365.              ExceptionMsg.FPR[i+7]);
  366.     }
  367.   }
  368. }
  369.  
  370. void    ShowRegsFPRHex(void)
  371. {
  372. int    i;
  373.   if (ExceptionMsg.SRR1 & MSRF_FP)
  374.   {
  375.     Printf("FPSCR %08lx\n",
  376.             ExceptionMsg.FPSCR);
  377.  
  378.     for (i=0;i<32;i+=8)
  379.     {
  380.       printf("FPR 0x%08lx%08lx 0x%08lx%08lx 0x%08lx%08lx 0x%08lx%08lx\n",
  381.              ((ULONG*) &ExceptionMsg.FPR[i+0])[0],((ULONG*) &ExceptionMsg.FPR[i+0])[1],
  382.              ((ULONG*) &ExceptionMsg.FPR[i+1])[0],((ULONG*) &ExceptionMsg.FPR[i+1])[1],
  383.              ((ULONG*) &ExceptionMsg.FPR[i+2])[0],((ULONG*) &ExceptionMsg.FPR[i+2])[1],
  384.              ((ULONG*) &ExceptionMsg.FPR[i+3])[0],((ULONG*) &ExceptionMsg.FPR[i+3])[1]);
  385.     }
  386.   }
  387. }
  388.  
  389. void    ShowRegsMMU(void)
  390. {
  391.   Printf("SDR1 %08lx\n",
  392.          ExceptionMsg.SDR1);
  393.  
  394.  
  395.   if (FALSE)
  396.   {
  397.     /* 64bit CPU */
  398.     Printf("ASR %08lx\n",
  399.            ExceptionMsg.ASR);
  400.   }
  401.  
  402.   if ((CPU==CPU_603) ||
  403.       (CPU==CPU_603e) ||
  404.       (CPU==CPU_603p))
  405.   {
  406.     Printf("DMISS %08lx DCMP %08lx IMISS %08lx ICMP %08lx\n",
  407.            ExceptionMsg.DMISS,
  408.            ExceptionMsg.DCMP,
  409.            ExceptionMsg.IMISS,
  410.            ExceptionMsg.ICMP);
  411.  
  412.     Printf("HASH1 %08lx HASH2 %08lx RPA %08lx\n",
  413.            ExceptionMsg.HASH1,
  414.            ExceptionMsg.HASH2,
  415.            ExceptionMsg.RPA);
  416.   }
  417.  
  418.   Printf("IBAT0U %08lx IBAT0L %08lx IBAT1U %08lx IBAT1L %08lx\n",
  419.          ExceptionMsg.IBAT0U,
  420.          ExceptionMsg.IBAT0L,
  421.          ExceptionMsg.IBAT1U,
  422.          ExceptionMsg.IBAT1L);
  423.  
  424.   Printf("IBAT2U %08lx IBAT2L %08lx IBAT3U %08lx IBAT3L %08lx\n",
  425.          ExceptionMsg.IBAT2U,
  426.          ExceptionMsg.IBAT2L,
  427.          ExceptionMsg.IBAT3U,
  428.          ExceptionMsg.IBAT3L);
  429.  
  430.   Printf("DBAT0U %08lx DBAT0L %08lx DBAT1U %08lx DBAT1L %08lx\n",
  431.          ExceptionMsg.DBAT0U,
  432.          ExceptionMsg.DBAT0L,
  433.          ExceptionMsg.DBAT1U,
  434.          ExceptionMsg.DBAT1L);
  435.  
  436.   Printf("DBAT2U %08lx DBAT2L %08lx DBAT3U %08lx DBAT3L %08lx\n",
  437.          ExceptionMsg.DBAT2U,
  438.          ExceptionMsg.DBAT2L,
  439.          ExceptionMsg.DBAT3U,
  440.          ExceptionMsg.DBAT3L);
  441.  
  442.   Printf("SR %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
  443.          ExceptionMsg.SR[0],
  444.          ExceptionMsg.SR[1],
  445.          ExceptionMsg.SR[2],
  446.          ExceptionMsg.SR[3],
  447.          ExceptionMsg.SR[4],
  448.          ExceptionMsg.SR[5],
  449.          ExceptionMsg.SR[6],
  450.          ExceptionMsg.SR[7]);
  451.  
  452.   Printf("SR %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
  453.          ExceptionMsg.SR[8],
  454.          ExceptionMsg.SR[9],
  455.          ExceptionMsg.SR[10],
  456.          ExceptionMsg.SR[11],
  457.          ExceptionMsg.SR[12],
  458.          ExceptionMsg.SR[13],
  459.          ExceptionMsg.SR[14],
  460.          ExceptionMsg.SR[15]);
  461.  
  462. }
  463.  
  464. void    ShowRegsMisc(void)
  465. {
  466.   Printf("PVR %08lx\n",
  467.          ExceptionMsg.PVR);
  468.  
  469.   Printf("SPRG0 %08lx SPRG1 %08lx SPRG2 %08lx SPRG3 %08lx\n",
  470.          ExceptionMsg.SPRG0,
  471.          ExceptionMsg.SPRG1,
  472.          ExceptionMsg.SPRG2,
  473.          ExceptionMsg.SPRG3);
  474.  
  475.   Printf("TBL %08lx TBU %08lx DEC %08lx DABA %08lx\n",
  476.          ExceptionMsg.TBL,
  477.          ExceptionMsg.TBU,
  478.          ExceptionMsg.DEC,
  479.          ExceptionMsg.DABR);
  480. }
  481.  
  482. void    ShowRegsFrame(void)
  483. {
  484.   Printf("PC %08lx MSR %08lx DAR %08lx DSISR %08lx\n",
  485.          ExceptionMsg.SRR0,
  486.          ExceptionMsg.SRR1,
  487.          ExceptionMsg.DAR,
  488.          ExceptionMsg.DSISR);
  489.  
  490.   Printf("CR %08lx XER %08lx LR %08lx CTR %08lx\n",
  491.          ExceptionMsg.CR,
  492.          ExceptionMsg.XER,
  493.          ExceptionMsg.LR,
  494.          ExceptionMsg.CTR);
  495. }
  496.  
  497. void    ShowRegs(void)
  498. {
  499.   ShowRegsFrame();
  500.   ShowRegsGPR();
  501.   ShowRegsFPRHex();
  502.   ShowRegsFPR();
  503.   ShowDiss(ExceptionMsg.SRR0,
  504.            1,
  505.            FALSE);
  506. }
  507.  
  508.  
  509. /*------------------------------------------------------------------------*/
  510. /*------------------------------------------------------------------------*/
  511. /*------------------------------------------------------------------------*/
  512. /*------------------------------------------------------------------------*/
  513. /*------------------------------------------------------------------------*/
  514. /*------------------------------------------------------------------------*/
  515. /*------------------------------------------------------------------------*/
  516. /*------------------------------------------------------------------------*/
  517.  
  518. BOOL    AddBreakPoint(ULONG    *Address)
  519. {
  520. struct BreakPoint    *MyBreakPoint;
  521.  
  522.   MyBreakPoint    =(struct BreakPoint*) BreakPointList.lh_Head;
  523.   while (MyBreakPoint->Node.ln_Succ)
  524.   {
  525.     if (MyBreakPoint->Address == Address)
  526.     {
  527.       return(TRUE);
  528.     }
  529.     MyBreakPoint    =(struct BreakPoint*) MyBreakPoint->Node.ln_Succ;
  530.   }
  531.  
  532.   if (MyBreakPoint=(struct BreakPoint*) AllocVec(sizeof(struct BreakPoint),MEMF_PUBLIC))
  533.   {
  534. //  __builtin_emit(0x4afc);
  535.     AddTail(&BreakPointList,
  536.             &MyBreakPoint->Node);
  537.  
  538.     MyBreakPoint->Address    =    Address;
  539.     MyBreakPoint->Opcode    =    PPCReadLong(MyBreakPoint->Address);
  540.  
  541.     PPCWriteLongFlush((ULONG*) MyBreakPoint->Address,
  542.                       OPCODE_TD31_0_0);
  543.     return(TRUE);
  544.   }
  545.   else
  546.   {
  547.     return(FALSE);
  548.   }
  549. }
  550.  
  551. BOOL    RemoveBreakPoint(ULONG    *Address)
  552. {
  553. struct BreakPoint    *MyBreakPoint;
  554.  
  555.   MyBreakPoint    =(struct BreakPoint*) BreakPointList.lh_Head;
  556.   while (MyBreakPoint->Node.ln_Succ)
  557.   {
  558.     if (MyBreakPoint->Address == Address)
  559.     {
  560.       Remove(&MyBreakPoint->Node);
  561.  
  562.       PPCWriteLongFlush(MyBreakPoint->Address,
  563.                         MyBreakPoint->Opcode);
  564.  
  565.       FreeVec(MyBreakPoint);
  566.       return(TRUE);
  567.     }
  568.     MyBreakPoint    =(struct BreakPoint*) MyBreakPoint->Node.ln_Succ;
  569.   }
  570.   return(FALSE);
  571. }
  572.  
  573. void    RemoveBreakPointAll(void)
  574. {
  575. struct BreakPoint    *MyBreakPoint;
  576. struct BreakPoint    *MyBreakPointSave;
  577.  
  578.   MyBreakPoint    =(struct BreakPoint*) BreakPointList.lh_Head;
  579.   while (MyBreakPoint->Node.ln_Succ)
  580.   {
  581.     Remove(&MyBreakPoint->Node);
  582.     MyBreakPointSave    =(struct BreakPoint*) MyBreakPoint->Node.ln_Succ;
  583.     FreeVec(MyBreakPoint);
  584.     MyBreakPoint    =    MyBreakPointSave;
  585.   }
  586. }
  587.  
  588. void    ShowBreakPointAll(void)
  589. {
  590. struct BreakPoint    *MyBreakPoint;
  591.  
  592.   MyBreakPoint    =(struct BreakPoint*) BreakPointList.lh_Head;
  593.   while (MyBreakPoint->Node.ln_Succ)
  594.   {
  595.     printf("Breakpoint at 0x%08lx with saved Opcode 0x%08lx\n",
  596.            MyBreakPoint->Address,
  597.            MyBreakPoint->Opcode);
  598.  
  599.     MyBreakPoint    =(struct BreakPoint*) MyBreakPoint->Node.ln_Succ;
  600.   }
  601. }
  602.  
  603.  
  604. struct BreakPoint    *CheckBreakPoint(ULONG    *Address)
  605. {
  606. struct BreakPoint    *MyBreakPoint;
  607.  
  608.   MyBreakPoint    =(struct BreakPoint*) BreakPointList.lh_Head;
  609.   while (MyBreakPoint->Node.ln_Succ)
  610.   {
  611.     if (MyBreakPoint->Address == Address)
  612.     {
  613.       return(MyBreakPoint);
  614.     }
  615.     MyBreakPoint    =(struct BreakPoint*) MyBreakPoint->Node.ln_Succ;
  616.   }
  617.   return(NULL);
  618. }
  619.  
  620.  
  621.  
  622. /*------------------------------------------------------------------------*/
  623. /*------------------------------------------------------------------------*/
  624. /*------------------------------------------------------------------------*/
  625. /*------------------------------------------------------------------------*/
  626. /*------------------------------------------------------------------------*/
  627. /*------------------------------------------------------------------------*/
  628. /*------------------------------------------------------------------------*/
  629. /*------------------------------------------------------------------------*/
  630.  
  631.  
  632. BOOL __asm ExceptionHookFunc(register __a0 struct Hook        *MyHook,
  633.                              register __a2 void            *MyTask,
  634.                              register __a1 struct ExceptionMsg    *MyMsg)
  635. {
  636.   ExceptionTask    =    MyTask;
  637.  
  638.   CopyMem(MyMsg,
  639.           &ExceptionMsg,
  640.           sizeof(struct ExceptionMsg));
  641.  
  642.   if (MsgProcess)
  643.   {
  644.     Signal(&MsgProcess->pr_Task,
  645.            1<<SIGNAL_EXCEPTION);
  646.     return(TRUE);
  647.   }
  648.   else
  649.   {
  650.     return(FALSE);
  651.   }
  652. }
  653.  
  654. /*------------------------------------------------------------------------*/
  655. /*------------------------------------------------------------------------*/
  656. /*------------------------------------------------------------------------*/
  657. /*------------------------------------------------------------------------*/
  658. /*------------------------------------------------------------------------*/
  659. /*------------------------------------------------------------------------*/
  660. /*------------------------------------------------------------------------*/
  661. /*------------------------------------------------------------------------*/
  662.  
  663.  
  664. ULONG    __asm AddressHookFunc(register __a0 struct Hook        *MyHook,
  665.                               register __a2 char        *MyBuffer,
  666.                               register __a1 ULONG        PC)
  667. {
  668.   return(0);
  669. }
  670.  
  671.  
  672. /*------------------------------------------------------------------------*/
  673. /*------------------------------------------------------------------------*/
  674. /*------------------------------------------------------------------------*/
  675. /*------------------------------------------------------------------------*/
  676. /*------------------------------------------------------------------------*/
  677. /*------------------------------------------------------------------------*/
  678. /*------------------------------------------------------------------------*/
  679. /*------------------------------------------------------------------------*/
  680.  
  681. ULONG    __asm SymbolHookFunc(register __a0 struct Hook        *MyHook,
  682.                              register __a2 char            *MyBuffer,
  683.                              register __a1 ULONG        PC)
  684. {
  685. struct PPCObjectInfo    MyInfo;
  686. struct TagItem        MyTags[1];
  687.  
  688.   MyInfo.Address    =    PC;
  689.   MyInfo.Name        =    NULL;
  690.   MyTags[0].ti_Tag    =    TAG_END;
  691.  
  692.   if (PPCGetObjectAttrs(MyObject,
  693.                         &MyInfo,
  694.                         MyTags))
  695.   {
  696. //  __builtin_emit(0x4afc);
  697.     if (PC == MyInfo.Address)
  698.     {
  699.       return((ULONG) sprintf(MyBuffer,"%s",
  700.                              MyInfo.Name));
  701.     }
  702.     else
  703.     {
  704.       return((ULONG) sprintf(MyBuffer,"%s+0x%lx",
  705.                              MyInfo.Name,
  706.                              PC - MyInfo.Address));
  707.     }
  708.   }
  709.   else
  710.   {
  711.     return(0);
  712.   }
  713. }
  714.  
  715. /*------------------------------------------------------------------------*/
  716. /*------------------------------------------------------------------------*/
  717. /*------------------------------------------------------------------------*/
  718. /*------------------------------------------------------------------------*/
  719. /*------------------------------------------------------------------------*/
  720. /*------------------------------------------------------------------------*/
  721. /*------------------------------------------------------------------------*/
  722. /*------------------------------------------------------------------------*/
  723.  
  724. ULONG    __asm RelocHookFunc(register __a0 struct Hook        *MyHook,
  725.                             register __a2 char            *MyBuffer,
  726.                             register __a1 ULONG            PC)
  727. {
  728. struct PPCObjectInfo    MyInfo;
  729. struct TagItem        MyTags[2];
  730. char            *AddressMode;
  731.  
  732.   MyInfo.Address    =    PC;
  733.   MyInfo.Name        =    NULL;
  734.   MyTags[0].ti_Tag    =    PPCELFINFOTAG_RELOC;
  735.   MyTags[0].ti_Data    =    TRUE;
  736.   MyTags[1].ti_Tag    =    TAG_END;
  737.  
  738. //  __builtin_emit(0x4afc);
  739.   if (PPCGetObjectAttrs(MyObject,
  740.                         &MyInfo,
  741.                         MyTags))
  742.   {
  743.     switch (MyInfo.SubType)
  744.     {
  745.       case    R_PPC_ADDR16_L:
  746.                 AddressMode    =    "@l";
  747.                 break;
  748.  
  749.       case    R_PPC_ADDR16_HI:
  750.                 AddressMode    =    "@hi";
  751.                 break;
  752.  
  753.       case    R_PPC_ADDR16_HA:
  754.                 AddressMode    =    "@ha";
  755.                 break;
  756.  
  757.       default:
  758.                 AddressMode    =    "";
  759.                 break;
  760.  
  761.     } 
  762.     return((ULONG) sprintf(MyBuffer,"%s%s",
  763.                            MyInfo.Name,
  764.                            AddressMode));
  765.   }
  766.   return(0);
  767. }
  768.  
  769. /*------------------------------------------------------------------------*/
  770. /*------------------------------------------------------------------------*/
  771. /*------------------------------------------------------------------------*/
  772. /*------------------------------------------------------------------------*/
  773. /*------------------------------------------------------------------------*/
  774. /*------------------------------------------------------------------------*/
  775. /*------------------------------------------------------------------------*/
  776. /*------------------------------------------------------------------------*/
  777.  
  778. void    __asm ScanHookFunc(register __a0 struct Hook        *MyHook,
  779.                            register __a2 void            *MyElfStruct,
  780.                            register __a1 struct PPCObjectInfo    *MyInfo)
  781.                             
  782. {
  783.   Printf("0x%08lx\t0x%08lx\t%s\n",
  784.          MyInfo->Address,
  785.          MyInfo->Size,
  786.          MyInfo->Name);
  787.  
  788. }
  789.  
  790. /*------------------------------------------------------------------------*/
  791. /*------------------------------------------------------------------------*/
  792. /*------------------------------------------------------------------------*/
  793. /*------------------------------------------------------------------------*/
  794. /*------------------------------------------------------------------------*/
  795. /*------------------------------------------------------------------------*/
  796. /*------------------------------------------------------------------------*/
  797. /*------------------------------------------------------------------------*/
  798.  
  799. BOOL    __asm ArgParserSymbolHookFunc(register __a0 struct Hook            *MyHook,
  800.                                       register __a2 char            *MyBuffer,
  801.                                       register __a1 struct SymbolHookMsg    *MyMsg)
  802. {
  803. char            LineBuffer[128];
  804. char            a;
  805. int            Length;
  806. struct TagItem        MyTags[1];
  807. struct PPCObjectInfo    MyInfo;
  808.  
  809.   Length=0;
  810.   while (((a=MyBuffer[Length]) >= 'a' && MyBuffer[Length] <= 'z') ||
  811.          (MyBuffer[Length] >= 'A' && MyBuffer[Length] <= 'Z') ||
  812.          (MyBuffer[Length] >= '0' && MyBuffer[Length] <= '9') ||
  813.          (MyBuffer[Length] >= '_'))
  814.   {
  815.     LineBuffer[Length]    =    a;
  816.     Length++;
  817.     if (Length > 126)
  818.     {
  819.       MyMsg->Error    =    ERROR_SYMBOLTOOLONG;
  820.       return(FALSE);
  821.     }
  822.   }
  823.   LineBuffer[Length]    =    '\0';
  824.   MyMsg->Length        =    Length;
  825.  
  826.   MyInfo.Name        =    LineBuffer;
  827.   MyInfo.Address    =    NULL;
  828.  
  829.   if (PPCGetObjectAttrs(MyObject,
  830.                         &MyInfo,
  831.                         MyTags))
  832.   {
  833. //    __builtin_emit(0x4afc);
  834.     MyMsg->Type        =    PARSETYPE_INTEGER;
  835.     *MyMsg->Integer    =    MyInfo.Address;
  836.     return(TRUE);
  837.   }
  838.   else
  839.   {
  840.     MyMsg->Error    =    ERROR_UNKNOWNSYMBOL;
  841.     return(FALSE);
  842.   }
  843.  
  844. }
  845.  
  846. /*------------------------------------------------------------------------*/
  847. /*------------------------------------------------------------------------*/
  848. /*------------------------------------------------------------------------*/
  849. /*------------------------------------------------------------------------*/
  850. /*------------------------------------------------------------------------*/
  851. /*------------------------------------------------------------------------*/
  852. /*------------------------------------------------------------------------*/
  853. /*------------------------------------------------------------------------*/
  854.  
  855. ULONG    __asm GetDataHookFunc(register __a0 struct Hook            *MyHook,
  856.                               register __a2 ULONG            *Address,
  857.                               register __a1 void            *Nobodycares)
  858. {
  859. struct BreakPoint    *MyBreakPoint;
  860.  
  861.   if (MyBreakPoint=CheckBreakPoint(Address))
  862.   {
  863.     return(MyBreakPoint->Opcode);
  864.   }
  865.   else
  866.   {
  867.     return(*Address);
  868.   }
  869. }
  870.  
  871.  
  872. /*------------------------------------------------------------------------*/
  873. /*------------------------------------------------------------------------*/
  874. /*------------------------------------------------------------------------*/
  875. /*------------------------------------------------------------------------*/
  876. /*------------------------------------------------------------------------*/
  877. /*------------------------------------------------------------------------*/
  878. /*------------------------------------------------------------------------*/
  879. /*------------------------------------------------------------------------*/
  880.  
  881. void    HandleInput(void)
  882. {
  883. char        MyBuffer[LINEMAX];
  884. struct TagItem    MyTags[10];
  885. ULONG        Length;
  886. ULONG        Lines;
  887. ULONG        Register;
  888. char        *Ptr;
  889. ULONG        Command;
  890. ULONG        CommandWord;
  891. ULONG        *TracePointAddress;
  892.  
  893. /*
  894.  * Each Exception set the default PC
  895.  */
  896.   PC        =    ExceptionMsg.SRR0;
  897.   MEM        =    ExceptionMsg.DAR;
  898.  
  899.   for (;;)
  900.   {
  901.     Printf(">");
  902.     Flush(OutputFile);
  903.     if (Length=Read(InputFile,&MyBuffer[0],LINEMAX))
  904.     {
  905.       MyBuffer[Length-1]    =    0;
  906.  
  907.       switch (tolower(MyBuffer[0]))
  908.       {
  909.         case    'g':
  910.                 if (tolower(MyBuffer[1]) == 's')
  911.                 {
  912.                   MyTracePoint.Address    =    EMPTYTRACEPOINT;
  913.                   MyTags[0].ti_Tag    =    PPCTASKSTARTTAG_TRACE;
  914.                   MyTags[0].ti_Data    =    TRUE;
  915.                   MyTags[1].ti_Tag    =    TAG_END;
  916.                   PPCStartTask(ExceptionTask,&MyTags[0]);
  917.                   GoSimulateFlag    =    TRUE;
  918.                   return;
  919.                 }
  920.                 else
  921.                 {
  922.                   MyTracePoint.Address    =    EMPTYTRACEPOINT;
  923.                   MyTags[0].ti_Tag    =    PPCTASKSTARTTAG_RUN;
  924.                   MyTags[0].ti_Data    =    TRUE;
  925.                   MyTags[1].ti_Tag    =    TAG_END;
  926.                   PPCStartTask(ExceptionTask,&MyTags[0]);
  927.                   return;
  928.                 }
  929.                 break;
  930.  
  931.         case    's':
  932.                 MyTracePoint.Address    =    EMPTYTRACEPOINT;
  933.                 MyTags[0].ti_Tag    =    PPCTASKSTARTTAG_TRACE;
  934.                 MyTags[0].ti_Data    =    TRUE;
  935.                 MyTags[1].ti_Tag    =    TAG_END;
  936.                 PPCStartTask(ExceptionTask,&MyTags[0]);
  937.                 return;
  938.                 break;
  939.  
  940.         case    't':
  941. //  __builtin_emit(0x4afc);
  942.                 CommandWord        =    *((ULONG*) ExceptionMsg.SRR0);
  943.                 Command            =    CommandWord >> (31-5);
  944.                 if ((Command == 0x10 && !(CommandWord & OPCODE_LR))                                || // bcx BO,BI,addr
  945.                     (Command == 0x12 && !(CommandWord & OPCODE_LR))                                || // bx addr
  946.                     (Command == 0x13 && MASK_21_30(CommandWord)== OP_ID(1,0,0,0,0,1,0,0,0,0) && !(CommandWord & OPCODE_LR))    || // bcctr
  947.                     (Command == 0x13 && MASK_21_30(CommandWord)== OP_ID(0,0,0,0,0,1,0,0,0,0) && !(CommandWord & OPCODE_LR))    || // bclrx
  948.                     (Command == 0x13 && MASK_21_30(CommandWord)== OP_ID(0,0,0,0,1,1,0,0,1,0)))                          // rfi
  949.                 {
  950.                   /* Use Single Step for commands which change the PC */
  951.                   MyTracePoint.Address    =    EMPTYTRACEPOINT;
  952.                   MyTags[0].ti_Tag    =    PPCTASKSTARTTAG_TRACE;
  953.                   MyTags[0].ti_Data    =    TRUE;
  954.                   MyTags[1].ti_Tag    =    TAG_END;
  955.                   PPCStartTask(ExceptionTask,&MyTags[0]);
  956.                 }
  957.                 else
  958.                 {
  959.  
  960.                   TracePointAddress        =    (ULONG*) (ExceptionMsg.SRR0+4);
  961.  
  962.                   /*
  963.                    * Check if the TracePointAddress is already
  964.                    * marked in the usual breakpoint list.
  965.                    * to avoid ugly Breakpoint overloading.
  966.                    */
  967.                   if (CheckBreakPoint(TracePointAddress) == NULL)
  968.                   {
  969.                     MyTracePoint.Address    =    TracePointAddress;
  970.                     MyTracePoint.Opcode        =    PPCReadLong(MyTracePoint.Address);
  971.  
  972.                     PPCWriteLongFlush((ULONG*) MyTracePoint.Address,
  973.                                       OPCODE_TD31_0_0);
  974.  
  975.                     MyTags[0].ti_Tag        =    PPCTASKSTARTTAG_RUN;
  976.                     MyTags[0].ti_Data        =    TRUE;
  977.                     MyTags[1].ti_Tag        =    TAG_END;
  978.                     PPCStartTask(ExceptionTask,&MyTags[0]);
  979.                   }
  980.                 }
  981.                 return;
  982.                 break;
  983.  
  984. /*
  985.  * I would have to change the Task/console to handle async events.
  986.  * No time for this release
  987.         case    'z':
  988.                 MyTags[0].ti_Tag    =    TAG_END;
  989.                 PPCStopTask(ExceptionTask,&MyTags[0]);
  990.                 return;
  991.                 break;
  992.  */
  993.  
  994.         case    'd':
  995. //  __builtin_emit(0x4afc);
  996.                 if (MyBuffer[1] != 'r')
  997.                 {
  998.                   Ptr        =    &MyBuffer[1];
  999.                   Lines        =    8;
  1000.  
  1001.                   if (Ptr=strtok(Ptr," "))
  1002.                   {
  1003.                     if (GetValue(Ptr,&PC))
  1004.                     {
  1005.                       if (Ptr=strtok(NULL," "))
  1006.                       {
  1007.                         GetValue(Ptr,&Lines);
  1008.                       }
  1009.                     }
  1010.                   }
  1011.                 }
  1012.                 else
  1013.                 {
  1014.                   PC    =    ExceptionMsg.LR;
  1015.                   Lines    =    8;
  1016.  
  1017.                   if (Ptr=strtok(&MyBuffer[2]," "))
  1018.                   {
  1019.                     GetValue(Ptr,&Lines);
  1020.                   }
  1021.                 }
  1022.  
  1023.                 if (ShowDiss(PC,
  1024.                              Lines,
  1025.                              TRUE))
  1026.                 {
  1027.                   PC        =    NewPC;
  1028.                 }
  1029.                 break;
  1030.  
  1031.  
  1032.         case    'm':
  1033.                 Ptr        =    &MyBuffer[1];
  1034.                 Lines        =    8;
  1035.  
  1036.                 if (Ptr=strtok(Ptr," "))
  1037.                 {
  1038.                   if (GetValue(Ptr,&MEM))
  1039.                   {
  1040.                     if (Ptr=strtok(NULL," "))
  1041.                     {
  1042.                       GetValue(Ptr,&Lines);
  1043.                     }
  1044.                   }
  1045.                 }
  1046.                 ShowMem(MEM,Lines);
  1047.                 break;
  1048.  
  1049.         case    'f':
  1050.                 {
  1051.                   struct PPCObjectInfo    MyInfo;
  1052.  
  1053.                   MyTags[0].ti_Tag    =    PPCELFINFOTAG_SCANSYMBOLHOOK;
  1054.                   MyTags[0].ti_Data    =    (ULONG) &MyScanSymbolHook;
  1055.                   MyTags[1].ti_Tag    =    TAG_END;
  1056.                   MyInfoStatus=PPCGetObjectAttrs(MyObject,
  1057.                                                  &MyInfo,
  1058.                                                  MyTags);
  1059.                 }
  1060.                 break;
  1061.  
  1062.         case    'r':
  1063.                 Ptr        =    &MyBuffer[1];
  1064. //  __builtin_emit(0x4afc);
  1065.  
  1066.                 if (Ptr=strtok(Ptr," ="))
  1067.                 {
  1068.                   if (((tolower(MyBuffer[1]) == 'g') || (tolower(MyBuffer[1]) == 'f')) &&
  1069.                        MyBuffer[2] == '[')
  1070.                   {
  1071.                     if (Length=stcd_l(&MyBuffer[3],(long*) &Register))
  1072.                     {
  1073.                       if ((Register <= 31) &&
  1074.                           MyBuffer[3+Length] == ']')
  1075.                       {
  1076.                         Ptr        =    &MyBuffer[3+Length+1];
  1077.                         if (Ptr=strtok(NULL," "))
  1078.                         {
  1079.                           ULONG        Error;
  1080.                           ULONG        Value;
  1081.                           double    DValue;
  1082.                           ULONG        Type;
  1083.                           void        *MyParseHandle;
  1084.  
  1085.                           MyTags[0].ti_Tag    =    PARSETAG_ERROR;
  1086.                           MyTags[0].ti_Data    =    (ULONG) &Error;
  1087.                           MyTags[1].ti_Tag    =    PARSETAG_VALUE;
  1088.  
  1089.                           if (tolower(MyBuffer[1]) == 'g')
  1090.                           {
  1091.                             Type        =    PARSETYPE_INTEGER;
  1092.                             MyTags[1].ti_Data    =    (ULONG) &Value;
  1093.                           }
  1094.                           else
  1095.                           {
  1096.                             Type        =    PARSETYPE_DOUBLE;
  1097.                             MyTags[1].ti_Data    =    (ULONG) &DValue;
  1098.                           }
  1099.  
  1100.                           MyTags[2].ti_Tag    =    PARSETAG_TYPE;
  1101.                           MyTags[2].ti_Data    =    (ULONG) &Type;
  1102.                           MyTags[3].ti_Tag    =    PARSETAG_SYMBOLHOOK;
  1103.                           MyTags[3].ti_Data    =    (ULONG) &MyArgParserSymbolHook;
  1104.                           MyTags[4].ti_Tag    =    TAG_END;
  1105.  
  1106.                           if (MyParseHandle=CreateParseHandle(MyTags))
  1107.                           {
  1108.                             MyTags[0].ti_Tag    =    TAG_END;
  1109.                             if (ParseArgument(MyParseHandle,
  1110.                                               Ptr,
  1111.                                               MyTags))
  1112.                             {
  1113.                               if (tolower(MyBuffer[1] == 'g'))
  1114.                               {
  1115.                                 printf("GPR[%ld] = 0x%08lx\n",
  1116.                                        Register,
  1117.                                        Value);
  1118.  
  1119.                                 ExceptionMsg.GPR[Register]    =    Value;
  1120.                                 MyTags[0].ti_Tag        =    PPCTASKINFOTAG_GPR;
  1121.                                 MyTags[0].ti_Data        =    Register;
  1122.                                 MyTags[1].ti_Tag        =    PPCTASKINFOTAG_VALUEPTR;
  1123.                                 MyTags[1].ti_Data        =    (ULONG) &Value;
  1124.                                 MyTags[2].ti_Tag        =    TAG_END;
  1125.                                 PPCSetTaskAttrs(ExceptionTask,
  1126.                                                 MyTags);
  1127.                               }
  1128.                               else
  1129.                               {
  1130.                                 printf("FPR[%ld] = %g\n",
  1131.                                        Register,
  1132.                                        DValue);
  1133.  
  1134.                                 ExceptionMsg.FPR[Register]    =    DValue;
  1135.                                 MyTags[0].ti_Tag        =    PPCTASKINFOTAG_FPR;
  1136.                                 MyTags[0].ti_Data        =    Register;
  1137.                                 MyTags[1].ti_Tag        =    PPCTASKINFOTAG_VALUEPTR;
  1138.                                 MyTags[1].ti_Data        =    (ULONG) &DValue;
  1139.                                 MyTags[2].ti_Tag        =    TAG_END;
  1140.                                 PPCSetTaskAttrs(ExceptionTask,
  1141.                                                MyTags);
  1142.                               }
  1143.                             }
  1144.                             else
  1145.                             {
  1146.                               printf("Error 0x%08lx\n",Error);
  1147.                             }
  1148.                             DeleteParseHandle(MyParseHandle);
  1149.                           }
  1150.                         }
  1151.                       }
  1152.                     }
  1153.                   }
  1154.                   else if (MyBuffer[1] == 'g')
  1155.  
  1156.                   {
  1157.                     ShowRegsGPR();
  1158.                   }
  1159.                   else if (MyBuffer[1] == 'f')
  1160.  
  1161.                   {
  1162.                     ShowRegsFPR();
  1163.                   }
  1164.                 }
  1165.                 else
  1166.                 {
  1167.                   ShowRegs();
  1168.                 }
  1169.                 break;
  1170.  
  1171.  
  1172.         case    '+':
  1173.                 ExceptionMsg.SRR0        +=    4;
  1174.                 MyTags[0].ti_Tag        =    PPCTASKINFOTAG_PC;
  1175.                 MyTags[0].ti_Data        =    (ULONG) &ExceptionMsg.SRR0;
  1176.                 MyTags[1].ti_Tag        =    TAG_END;
  1177.                 PPCSetTaskAttrs(ExceptionTask,
  1178.                                MyTags);
  1179.                 break;
  1180.  
  1181.         case    '-':
  1182.                 ExceptionMsg.SRR0        -=    4;
  1183.                 MyTags[0].ti_Tag        =    PPCTASKINFOTAG_PC;
  1184.                 MyTags[0].ti_Data        =    (ULONG) &ExceptionMsg.SRR0;
  1185.                 MyTags[1].ti_Tag        =    TAG_END;
  1186.                 PPCSetTaskAttrs(ExceptionTask,
  1187.                                MyTags);
  1188.                 break;
  1189.  
  1190.         case    '?':
  1191.                 Ptr        =    &MyBuffer[1];
  1192.                 if (Ptr=strtok(Ptr," "))
  1193.                 {
  1194.                   ULONG    Error;
  1195.                   ULONG    Value;
  1196.                   ULONG    Type;
  1197.                   void    *MyParseHandle;
  1198.  
  1199.                   Type            =    PARSETYPE_INTEGER;
  1200.                   MyTags[0].ti_Tag    =    PARSETAG_ERROR;
  1201.                   MyTags[0].ti_Data    =    (ULONG) &Error;
  1202.                   MyTags[1].ti_Tag    =    PARSETAG_VALUE;
  1203.                   MyTags[1].ti_Data    =    (ULONG) &Value;
  1204.                   MyTags[2].ti_Tag    =    PARSETAG_TYPE;
  1205.                   MyTags[2].ti_Data    =    (ULONG) &Type;
  1206.                   MyTags[3].ti_Tag    =    PARSETAG_SYMBOLHOOK;
  1207.                   MyTags[3].ti_Data    =    (ULONG) &MyArgParserSymbolHook;
  1208.                   MyTags[4].ti_Tag    =    TAG_END;
  1209.  
  1210.                   if (MyParseHandle=CreateParseHandle(MyTags))
  1211.                   {
  1212.                     MyTags[0].ti_Tag    =    TAG_END;
  1213.                     if (ParseArgument(MyParseHandle,
  1214.                                       Ptr,
  1215.                                       MyTags))
  1216.                     {
  1217.                       printf("= 0x%08lx\n",Value);
  1218.                     }
  1219.                     else
  1220.                     {
  1221.                       printf("Error 0x%08lx\n",Error);
  1222.                     }
  1223.                     DeleteParseHandle(MyParseHandle);
  1224.                   }
  1225.                 }
  1226.                 break;
  1227.  
  1228.  
  1229.         case    'b':
  1230.                 if (MyBuffer[1]=='s')
  1231.                 {
  1232.                   ShowBreakPointAll();
  1233.                   break;
  1234.                 }
  1235.  
  1236.                 if (MyBuffer[1]=='r')
  1237.                 {
  1238.                   Ptr        =    &MyBuffer[2];
  1239.                 }
  1240.                 else
  1241.                 {
  1242.                   Ptr        =    &MyBuffer[1];
  1243.                 }
  1244.                 if (Ptr=strtok(Ptr," "))
  1245.                 {
  1246.                   ULONG    Error;
  1247.                   ULONG    Value;
  1248.                   ULONG    Type;
  1249.                   void    *MyParseHandle;
  1250.  
  1251.                   Type            =    PARSETYPE_INTEGER;
  1252.                   MyTags[0].ti_Tag    =    PARSETAG_ERROR;
  1253.                   MyTags[0].ti_Data    =    (ULONG) &Error;
  1254.                   MyTags[1].ti_Tag    =    PARSETAG_VALUE;
  1255.                   MyTags[1].ti_Data    =    (ULONG) &Value;
  1256.                   MyTags[2].ti_Tag    =    PARSETAG_TYPE;
  1257.                   MyTags[2].ti_Data    =    (ULONG) &Type;
  1258.                   MyTags[3].ti_Tag    =    PARSETAG_SYMBOLHOOK;
  1259.                   MyTags[3].ti_Data    =    (ULONG) &MyArgParserSymbolHook;
  1260.                   MyTags[4].ti_Tag    =    TAG_END;
  1261.  
  1262.                   if (MyParseHandle=CreateParseHandle(MyTags))
  1263.                   {
  1264.                     MyTags[0].ti_Tag    =    TAG_END;
  1265.                     if (ParseArgument(MyParseHandle,
  1266.                                       Ptr,
  1267.                                       MyTags))
  1268.                     {
  1269.                       if (MyBuffer[1]=='r')
  1270.                       {
  1271.                         if (RemoveBreakPoint((ULONG*) Value))
  1272.                         {
  1273.                           printf("No Breakpoint at 0x%08lx found\n",Value);
  1274.                         }
  1275.                         else
  1276.                         {
  1277.                           printf("Breakpoint at 0x%08lx removed\n",Value);
  1278.                         }
  1279.                       }
  1280.                       else
  1281.                       {
  1282.                         if (AddBreakPoint((ULONG*) Value))
  1283.                         {
  1284.                           printf("Breakpoint at 0x%08lx added\n",Value);
  1285.                         }
  1286.                       }
  1287.                     }
  1288.                     else
  1289.                     {
  1290.                       printf("Error 0x%08lx\n",Error);
  1291.                     }
  1292.                     DeleteParseHandle(MyParseHandle);
  1293.                   }
  1294.                 }
  1295.                 break;
  1296.  
  1297.  
  1298.         case    'h':
  1299.                 Printf("(h)elp\n");
  1300.                 Printf("(g)o\n");
  1301.                 Printf("(gs) go with single step\n");
  1302.                 Printf("(t)race\n");
  1303.                 Printf("(s)ingle step\n");
  1304.                 Printf("(z)top..sorry..can`t work because of the sync design\n");
  1305.                 Printf("(d)isassemble [Address] [Lines]\n");
  1306.                 Printf("(dr)isassemble-LR-Register [Lines]\n");
  1307.                 Printf("(m)emory [Address] [Lines]\n");
  1308.                 Printf("(r)egister dump\n");
  1309.                 Printf("(rg) show GPR registers\n");
  1310.                 Printf("(rf) show FPR registers\n");
  1311.                 Printf("(rg[GPR Reg] Value) set GPR register\n");
  1312.                 Printf("(rf[FPR Reg] Value) set FPR register\n");
  1313.                 Printf("(b Value) add Breakpoint\n");
  1314.                 Printf("(br Value) remove Breakpoint\n");
  1315.                 Printf("(bs) show Breakpoint\n");
  1316.                 Printf("(f) Symbol dump\n");
  1317.                 Printf("(? Value)\n");
  1318.                 Printf("(+) Next Instruction\n");
  1319.                 Printf("(-) Previous Instruction\n");
  1320.                 break;
  1321.       }
  1322.     }
  1323.   }
  1324. }
  1325.  
  1326. /*------------------------------------------------------------------------*/
  1327. /*------------------------------------------------------------------------*/
  1328. /*------------------------------------------------------------------------*/
  1329. /*------------------------------------------------------------------------*/
  1330. /*------------------------------------------------------------------------*/
  1331. /*------------------------------------------------------------------------*/
  1332. /*------------------------------------------------------------------------*/
  1333. /*------------------------------------------------------------------------*/
  1334.  
  1335. void MsgTask(void)
  1336. {
  1337. struct Process    *MyTask;
  1338. struct TagItem    MyTags[10];
  1339. ULONG        SignalMask;
  1340. BPTR        OldInputFile;
  1341. BPTR        OldOutputFile;
  1342.  
  1343.  
  1344.   MyTask                =(struct Process*) FindTask(NULL);
  1345.   OldInputFile                =    MyTask->pr_CIS;
  1346.   OldOutputFile                =    MyTask->pr_COS;
  1347.   MyTask->pr_CIS            =    InputFile;
  1348.   MyTask->pr_COS            =    OutputFile;
  1349.   MyInfo.Address            =    0;
  1350.   MyInfo.Size                =    0;
  1351.   MyInfoStatus                =    FALSE;
  1352.   GoSimulateFlag            =    FALSE;
  1353.  
  1354.   MyAddressHook.h_Entry            =    (ULONG (*)(void)) AddressHookFunc;
  1355.   MyAddressHook.h_SubEntry        =    (ULONG (*)(void)) NULL;
  1356.   MyAddressHook.h_Data            =    (APTR) PPCLibBase;
  1357.  
  1358.   MySymbolHook.h_Entry            =    (ULONG (*)(void)) SymbolHookFunc;
  1359.   MySymbolHook.h_SubEntry        =    (ULONG (*)(void)) NULL;
  1360.   MySymbolHook.h_Data            =    (APTR) PPCLibBase;
  1361.  
  1362.   MyRelocHook.h_Entry            =    (ULONG (*)(void)) RelocHookFunc;
  1363.   MyRelocHook.h_SubEntry        =    (ULONG (*)(void)) NULL;
  1364.   MyRelocHook.h_Data            =    (APTR) PPCLibBase;
  1365.  
  1366.   MyScanSymbolHook.h_Entry        =    (ULONG (*)(void)) ScanHookFunc;
  1367.   MyScanSymbolHook.h_SubEntry        =    (ULONG (*)(void)) NULL;
  1368.   MyScanSymbolHook.h_Data        =    (APTR) PPCLibBase;
  1369.  
  1370.   MyArgParserSymbolHook.h_Entry        =    (ULONG (*)(void)) ArgParserSymbolHookFunc;
  1371.   MyArgParserSymbolHook.h_SubEntry    =    (ULONG (*)(void)) NULL;
  1372.   MyArgParserSymbolHook.h_Data        =    (APTR) PPCLibBase;
  1373.  
  1374.   MyGetDataHook.h_Entry            =    (ULONG (*)(void)) GetDataHookFunc;
  1375.   MyGetDataHook.h_SubEntry        =    (ULONG (*)(void)) NULL;
  1376.   MyGetDataHook.h_Data            =    (APTR) PPCLibBase;
  1377.  
  1378.  
  1379.   NewList(&BreakPointList);
  1380.  
  1381.   MyTags[0].ti_Tag            =    PPCINFOTAG_CPU;
  1382.   MyTags[1].ti_Tag            =    TAG_END;
  1383.   CPU                    =    PPCGetAttrs((struct TagItem*) &MyTags);
  1384.  
  1385.   /*
  1386.    * Disable Tracepoint
  1387.    */
  1388.   MyTracePoint.Address            =    EMPTYTRACEPOINT;
  1389.  
  1390.   while ((SignalMask=Wait(1<<SIGNAL_EXCEPTION | 1<<SIGBREAKB_CTRL_C)) == 1<<SIGNAL_EXCEPTION)
  1391.   {
  1392.     Printf("----------------------------------------------------------\n");
  1393.     if (!(ExceptionMsg.Type & EXCEPTION_MSG))
  1394.     {
  1395.       /* Hardware Exception */
  1396.  
  1397.       if (MyTracePoint.Address != EMPTYTRACEPOINT)
  1398.       {
  1399.         /*
  1400.          * Remove tracetrap..doesn`t matter if it hit
  1401.          */
  1402.  
  1403.         PPCWriteLongFlush(MyTracePoint.Address,
  1404.                           MyTracePoint.Opcode);
  1405.  
  1406.         MyTracePoint.Address    = EMPTYTRACEPOINT;
  1407.       }
  1408.  
  1409.       RemoveBreakPoint((ULONG*) ExceptionMsg.SRR0);
  1410.  
  1411.       Printf("Exception: Type 0x%lx %s\n",
  1412.              ExceptionMsg.Type,
  1413.              ExceptionMsg.Type > (sizeof(ExceptionStringTable)/4) ? "Illegal ID" : ExceptionStringTable[ExceptionMsg.Type]);
  1414.     }
  1415.     else
  1416.     {
  1417.       /* Kernel Notify Exception */
  1418.     }
  1419.  
  1420.  
  1421.     if (ExceptionMsg.Type != EXCEPTION_FINISHTASK)
  1422.     {
  1423.       if ((ExceptionMsg.Type == EXCEPTION_DATAACCESS) ||
  1424.           (ExceptionMsg.Type == EXCEPTION_INSTRUCTIONACCESS))
  1425.       {
  1426.         Printf("Illegal Memory Access at %08lx\n",
  1427.                 ExceptionMsg.DAR);
  1428.       }
  1429.  
  1430.       if (ExceptionMsg.Type != EXCEPTION_TRACE)
  1431.       {
  1432.         /* Switch off Simulate Mode and stop for a non trace exception
  1433.          */
  1434.         GoSimulateFlag    =    FALSE;
  1435.       }
  1436.  
  1437.  
  1438.       ShowRegs();
  1439.  
  1440.       if (GoSimulateFlag)
  1441.       {
  1442.         MyTracePoint.Address    =    EMPTYTRACEPOINT;
  1443.         MyTags[0].ti_Tag    =    PPCTASKSTARTTAG_TRACE;
  1444.         MyTags[0].ti_Data    =    TRUE;
  1445.         MyTags[1].ti_Tag    =    TAG_END;
  1446.         PPCStartTask(ExceptionTask,&MyTags[0]);
  1447.       }
  1448.       else
  1449.       {
  1450.         HandleInput();
  1451.       }
  1452.     }
  1453.     else
  1454.     {
  1455.       RemoveBreakPointAll();
  1456.       Printf("Task has finished...\n");
  1457.     }
  1458.   }
  1459.   MyTask->pr_CIS    =    OldInputFile;
  1460.   MyTask->pr_COS    =    OldOutputFile;
  1461.   MsgProcess=NULL;
  1462. }
  1463.  
  1464.  
  1465. /*------------------------------------------------------------------------*/
  1466. /*------------------------------------------------------------------------*/
  1467. /*------------------------------------------------------------------------*/
  1468. /*------------------------------------------------------------------------*/
  1469. /*------------------------------------------------------------------------*/
  1470. /*------------------------------------------------------------------------*/
  1471. /*------------------------------------------------------------------------*/
  1472. /*------------------------------------------------------------------------*/
  1473.  
  1474.  
  1475. void    main(ULONG argc,char *argv[])
  1476. {
  1477. ULONG        Result;
  1478. struct TagItem    MyTags[10];
  1479.  
  1480.   stdout    =    Output();
  1481.  
  1482.   if(argc != 2L)
  1483.   {
  1484.     Printf("Usage: Name\n");
  1485.   }
  1486.   else
  1487.   if (PPCLibBase=OpenLibrary("ppc.library",0))
  1488.   {
  1489.     if (PPCDissBase=OpenLibrary("ppcdiss.library",0L))
  1490.     {
  1491.       if (MyObject=PPCLoadObject(argv[1]))
  1492.       {
  1493.         InputFile        =    Input();
  1494.         OutputFile        =    Output();
  1495.  
  1496.     #if    0
  1497. /************************************************************
  1498.  *
  1499.  *
  1500.  *                MEGA HACK extraordinaire
  1501.  *      Don`t copy or you`ll suffer in programmer hell.
  1502.  *      SAS uses a stackcheck in certain string lib functions
  1503.  *    which doesn`t work with hooks/several tasks.
  1504.  *             So i fool the stackcheck code.
  1505.  *     Will be removed when Steve compiles a new libm881nb.lib
  1506.  *     and release the final 6.58 patch
  1507.  *
  1508.  ************************************************************/
  1509.         __base            =    0;
  1510.         #endif
  1511.  
  1512.  
  1513.  
  1514.         MyTags[0].ti_Tag    =    NP_Entry;
  1515.         MyTags[0].ti_Data    =(ULONG) &MsgTask;
  1516.         MyTags[1].ti_Tag    =    NP_Name;
  1517.         MyTags[1].ti_Data    =(ULONG) "PPCDebug: MsgTask";
  1518.         MyTags[2].ti_Tag    =    TAG_END;
  1519.  
  1520.         if (MsgProcess=CreateNewProc(&MyTags[0]))
  1521.         {
  1522.           MyHook.h_Entry    =    (ULONG (*)(void)) ExceptionHookFunc;
  1523.           MyHook.h_SubEntry    =    (ULONG (*)(void)) NULL;
  1524.           MyHook.h_Data        =    (APTR) PPCLibBase;
  1525.  
  1526.           MyTags[0].ti_Tag    =    PPCTASKTAG_STOPTASK;
  1527.           MyTags[0].ti_Data    =    TRUE;
  1528.           MyTags[1].ti_Tag    =    PPCTASKTAG_WAITFINISH;
  1529.           MyTags[1].ti_Data    =    TRUE;
  1530.           MyTags[2].ti_Tag    =    PPCTASKTAG_EXCEPTIONHOOK;
  1531.           MyTags[2].ti_Data    =    (ULONG) &MyHook;
  1532.           MyTags[3].ti_Tag    =    TAG_END;
  1533.  
  1534.           Result=(ULONG) PPCCreateTask(MyObject,
  1535.                                        &MyTags[0]);
  1536.  
  1537.  
  1538.  
  1539.           printf("Result:0x%lx\n",Result);
  1540.           if (MsgProcess)
  1541.           {
  1542.             Signal(&MsgProcess->pr_Task,
  1543.                    1<<SIGBREAKB_CTRL_C);
  1544.             while (MsgProcess);
  1545.           }
  1546.         }
  1547.         else
  1548.         {
  1549.           Printf("Can't create debugger msg task\n");
  1550.         }
  1551.         PPCUnLoadObject(MyObject);
  1552.       }
  1553.       else
  1554.       {
  1555.         Printf("Can't load %s\n",argv[1]);
  1556.       }
  1557.       CloseLibrary(PPCDissBase);
  1558.     }
  1559.     else
  1560.     {
  1561.       Printf("Can't open ppcdiss.library\n");
  1562.     }
  1563.     CloseLibrary(PPCLibBase);
  1564.   }
  1565. }
  1566.